/*
 *  ground.cpp
 *  EPPI-0.0
 *
 *  Created by Juan Carlos Garcia Orden on 27/04/11
 */

#include "ground.h"

Ground::Ground(ifstream &in, string cname, MecSystem *pSys)
:	Body(in,cname,pSys)
{	
	dim = parentSystem->dim;	/** Must be set always.  dim belongs to the mother class Body */
	type = "ground";
	
	int i;
	int j;

	char keyword[20];
	string auxs;				/** Aux string */
	vector<string> auxsv(4);
//	vector<vector<double> > matRel;	// row: coordinates of a relative vector. 3 rows, 3 columns each
	cm.resize(dim);			// Principal moments of inertia
//	vector<double> pmInertia(dim);			// Principal moments of inertia
//	double mass;
	R.resize(dim);		// Initial rotation matrix
	for (i=0; i<dim; ++i)	R[i].resize(dim);
//	vector<double> coords(dim);
/*
	matRel.resize(3);
	for (i = 0; i < matRel.size(); ++i)
		matRel[i].resize(3);
	
	R.resize(3);
	for (i = 0; i < R.size(); ++i)	R[i].resize(3);
*/
	
	while (in >> keyword && strcmp(keyword,"ENDBODY") )
	{
		// Keyword has the CM label
		// Reads the coordinates of the center of mass (cm)
		in >> cm[0];
		if (dim>=2)	in >> cm[1];
		if (dim==3)	in >> cm[2];
	
		// Reads the orientation of the principal axes
		in >> auxs;	// ORIENTATION label
		for (i=0; i<dim; ++i)
		{
			for (j=0; j<dim; ++j)
			{
				in >> R[i][j];
			}
		}
				
		// Read the name of the graphical object
		in >> auxs;	// SURFACE 
		in >> surfName;
	
		// Read the coordinates of the local points
		// all means that the local points are all points of the visualization mesh
		// filename.dat reads the coordinates from the file
		in >> auxs;
		/*
		if (!auxs.compare("LOCALPOINTS"))
		{
		}
		else if(!auxs.compare("ENDBODY")) break;
		*/
		if(!auxs.compare("ENDBODY")) break;
	}
	
	// If nothing is said about contact, take by default the "all" option
	if (contactAllOption==false && contactFileOption==false)	contactAllOption = true;
	
	localSystem.resize(dim*(dim+1));	// 12 for dim=3.  6 for dim=2
	for (i=0; i<dim; ++i)	localSystem[i] = cm[i];
	// Other points, at unit distance oriented by R
	if (dim==3)
	{
		vector<double> auxE1(dim);
		vector<double> auxE2(dim);
		vector<double> auxE3(dim);
		
		auxE1[0] = 1.0;
		auxE2[1] = 1.0;
		auxE3[2] = 1.0;
		// P1 = cm + R*[1,0,0]
		rigidTransOver(auxE1,cm,R);
		rigidTransOver(auxE2,cm,R);
		rigidTransOver(auxE3,cm,R);
		localSystem[3] = auxE1[0];
		localSystem[4] = auxE1[1];
		localSystem[5] = auxE1[2];
		localSystem[6] = auxE2[0];
		localSystem[7] = auxE2[1];
		localSystem[8] = auxE2[2];
		localSystem[9] = auxE3[0];
		localSystem[10] = auxE3[1];
		localSystem[11] = auxE3[2];
	}
	else if (dim==2)	{}	// TO BE DONE
	
	
	if(parentSystem->getProcNum()==parentSystem->getRankNum())
	cout << "	Body " << name << " succesfully read \n";
}

// ***

void Ground::setPTPointsComp()
{
	int j, k;
	vector<string> auxs;
	map<string, Point*, less<string> > maux;
	pair<string,Point*> mauxEntry;
	pair<string,int> sharedEntry;
	
	for (j = 0; j < vComponents.size(); j++)		
	//Loop on the components
	{
		auxs = (vComponents[j]->getPointNames());
		for(k = 0; k < auxs.size(); k++)		
		// Loop on the names of the points within each component
		{
			/** If the point it is not at the local process ... */
			if( (parentSystem->checkIfPointProcess(auxs[k])) == false )
			{
//				 cout << "Punto " << auxs[k] << " es remoto, estoy en el sistema " << parentSystem->name << endl;
				/** ...  create it at root system, copying the original point from the remote process */
				parentSystem->createPointAtRoot( parentSystem->getPTPoint(auxs[k]) );
				/** ...  and add the name of the shared point at the remote process */
				parentSystem->addRemoteSharedPoint(auxs[k],parentSystem->getProcNum());
			}
			mauxEntry.first = auxs[k];
			mauxEntry.second = (parentSystem->getPTPointLocal(auxs[k]));
			maux.insert(mauxEntry);
		}
		vComponents[j]->setMPoints(maux);
		maux.clear();
	}
}

// ***

void Ground::setPTPointsLoad()
{
	int j, k;
	vector<string> auxs;
	map<string, Point*, less<string> > maux;
	pair<string,Point*> mauxEntry;
	pair<string,int> sharedEntry;
	
	for(j=0; j<vLoads.size(); j++)		
	//Loop on the Loads
	{
		auxs = (vLoads[j]->getPointNames());
		for(k=0; k<auxs.size(); k++)		
		// Loop on the names of the points within each component
		{
			/** If the point it is not at the local process ... */
			if( (parentSystem->checkIfPointProcess(auxs[k]))==false )
			{
				/** ...  create it at root system, copying the original point from the remote process */
				parentSystem->createPointAtRoot( parentSystem->getPTPoint(auxs[k]) );
				/** ...  and add the name of the shared point at the remote process */
				parentSystem->addRemoteSharedPoint(auxs[k],parentSystem->getProcNum());
			}
			mauxEntry.first = auxs[k];
			mauxEntry.second = (parentSystem->getPTPointLocal(auxs[k]));
			maux.insert(mauxEntry);
		}
		vLoads[j]->setMPoints(maux);
		maux.clear();
	}
}

// ***

void Ground::setPPointSurface()
{}

// ***
void Ground::setMatAtComp()
{}

// ***
void Ground::getBoundary(vector<vector<string> >& connect)
{}

// ***

void Ground::writeMSH(ofstream &fGraph)
{}

// ***

void Ground::writeVTU(ofstream &fGraph, bool& plotDispFlag, bool& plotProcFlag, bool& plotStressFlag)
{
	surface->writeVTU(cm,R,localFGraph);
}

// ***

void Ground::writeOOGL(ofstream &fGraph)
{}

// ***

void Ground::writeFileTemp(const double& time, ofstream & outF)
{}

// ***

void Ground::setIniPosBody(vector<double>& iniValues)
{}